package com.ebai.product.management.service.system;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.ebai.product.management.base.cache.service.MessageCacheImpl;
import com.ebai.product.management.base.cache.service.ReportCacheImpl;
import com.ebai.product.management.base.utils.Common;
import com.ebai.product.management.base.utils.SysCode;
import com.ebai.product.management.model.entity.User;
import com.ebai.product.management.model.vojo.RoleUserVo;
import com.ebai.product.management.repository.system.UserRepository;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;
    
    public Page<RoleUserVo> queryPageByRole(Integer page, Integer size, String rolePid) {
    	Pageable pageable = PageRequest.of(page-1, size, Sort.Direction.DESC, "createTime");
    	Page<RoleUserVo> userPage = this.userRepository.findAllByRole(rolePid, pageable);
    	
    	return userPage;
    }

    /**
     * 依据条件查询分页数据
     * @param page
     * @param size
     * @param userQuery
     * @return
     */
    public Page<User> queryPage(Integer page, Integer size, final User userQuery) {
        Pageable pageable = PageRequest.of(page-1, size, Sort.Direction.DESC, "createTime");
        Page<User> userPage = this.userRepository.findAll(new Specification<User>(){
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                // 过滤内置管理员用户
                list.add(criteriaBuilder.notEqual(root.get("loginName").as(String.class), SysCode.DEFAULT_USER.DEFAULT_SA));
                // 过滤已经删除的用户
                list.add(criteriaBuilder.notEqual(root.get("isDelete").as(String.class), SysCode.DICT_TYSF.YES));

                // 过滤登录账号条件
                if ( StringUtils.isNotBlank(userQuery.getLoginName()) ){
                    list.add(criteriaBuilder.like(root.get("loginName").as(String.class), "%"+ userQuery.getLoginName() +"%"));
                }
                // 过滤用户名称条件
                if ( StringUtils.isNotBlank(userQuery.getUserName()) ){
                    list.add(criteriaBuilder.like(root.get("userName").as(String.class), "%"+ userQuery.getUserName() +"%"));
                }
                // 过滤手机号码条件
                if ( StringUtils.isNotBlank(userQuery.getMobileNo()) ){
                    list.add(criteriaBuilder.like(root.get("mobileNo").as(String.class), "%"+ userQuery.getMobileNo() +"%"));
                }
                // 过滤是否启用条件
                if ( StringUtils.isNotBlank(userQuery.getIsEnable()) ){
                    list.add(criteriaBuilder.equal(root.get("isEnable").as(String.class), userQuery.getIsEnable()));
                }
                // 过滤创建时间条件
                if ( StringUtils.isNotBlank(userQuery.getCreateTimeBetween()) ){
                    String[] createTime = userQuery.getCreateTimeBetween().split(" ~ ");
                    list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(Timestamp.class), Timestamp.valueOf(createTime[0] + " 00:00:00")));
                    list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(Timestamp.class), Timestamp.valueOf(createTime[1] + " 23:59:59")));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, pageable);

        return userPage;
    }

    /**
     * 依据条件查询对象是否存在
     * @param loginName
     * @return
     */
    public Map<String, Object> checkExist(String loginName) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", true);

        User user = this.queryByLoginName(loginName);
        if (null != user) {
            result.put("msg", MessageCacheImpl.getMsg("UserService.checkExist.Message.ERR1"));
        }
        else {
            String[] reserveWord = ReportCacheImpl.getReportSql("reserveWord").split(",");
            for (String word : reserveWord) {
                if (StringUtils.equalsIgnoreCase(word.trim(), loginName.trim())) {
                    result.put("success", true);
                    result.put("msg", MessageCacheImpl.getMsg("UserService.checkExist.Message.ERR2"));
                }
            }
        }

        return result;
    }

    /**
     * 依据条件获取数据对象
     * @param loginName
     * @return
     */
    public User queryByLoginName(String loginName) {
        return this.userRepository.findUserByLoginName(loginName);
    }

    /**
     * 依据条件获取数据对象
     * @param loginName
     * @param loginPasswd
     * @return
     */
    public User queryByLoginName(String loginName, String loginPasswd) {
        return this.userRepository.findUserByLoginName(loginName, loginPasswd);
    }

    /**
     * 保存或更新表单数据
     * @param entity
     * @return
     */
    public Map<String, Object> saveData(User entity) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", Boolean.FALSE);

        try {
            if (StringUtils.isBlank(entity.getPid())) {
                entity.setLoginPasswd(SysCode.DEFAULT_USER.MD5_DEF_SALT);
                entity.setIsDelete(SysCode.DICT_TYSF.NO);
                this.userRepository.save(entity);
            }
            else {
                User user = this.userRepository.findByPid(entity.getPid());
                user.setUserName(entity.getUserName());
                user.setMobileNo(entity.getMobileNo());
                if (StringUtils.isNotBlank(entity.getIsEnable())) {
                    user.setIsEnable(entity.getIsEnable());
                }
                user.setLastUpdateTime(null);
                this.userRepository.save(user);
            }

            result.put("success", Boolean.TRUE);
            result.put("msg", MessageCacheImpl.getMsg("Global.SaveData.Message.Success"));
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("msg", MessageCacheImpl.getMsg("Global.SaveData.Message.Failure") + e.getMessage());
        }

        return result;
    }

    /**
     * 修改更新用户密码
     * @param pid
     * @param newPasswd
     * @return
     */
    public Map<String, Object> changePwd(String pid, String newPasswd) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", Boolean.FALSE);

        try {
            User user = this.userRepository.findByPid(pid);
            user.setLoginPasswd(Common.EncryptMD5(newPasswd + SysCode.DEFAULT_USER.SALT, Common.MD5_LX_32));
            this.userRepository.save(user);

            result.put("success", Boolean.TRUE);
            result.put("msg", MessageCacheImpl.getMsg("UserService.undoPasswd.Message.Success"));
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("msg", MessageCacheImpl.getMsg("UserService.undoPasswd.Message.Failure") + e.getMessage());
        }

        return result;
    }

    /**
     * 依据主键执行逻辑删除
     * @param ids
     * @return
     */
    public Map<String, Object> dropData(String ids) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", Boolean.FALSE);

        try {
            if (StringUtils.isNotBlank(ids)) {
                for (String pid : ids.split(",")) {
                    User entity = this.userRepository.findByPid(pid);
                    entity.setIsDelete(SysCode.DICT_TYSF.YES);
                    this.userRepository.save(entity);
                }
            }

            result.put("success", Boolean.TRUE);
            result.put("msg", MessageCacheImpl.getMsg("Global.DeleteData.Message.Success"));
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("msg", MessageCacheImpl.getMsg("Global.DeleteData.Message.Failure") + e.getMessage());
        }

        return result;
    }

    /**
     * 依据主键执行密码重置
     * @param ids
     * @return
     */
    public Map<String, Object> undoPasswd(String ids) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", Boolean.FALSE);

        try {
            if (StringUtils.isNotBlank(ids)) {
                for (String pid : ids.split(",")) {
                    User entity = this.userRepository.findByPid(pid);
                    entity.setLoginPasswd(SysCode.DEFAULT_USER.MD5_DEF_SALT);
                    this.userRepository.save(entity);
                }
            }

            result.put("success", Boolean.TRUE);
            result.put("msg", MessageCacheImpl.getMsg("UserService.undoPasswd.Message.Success"));
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("msg", MessageCacheImpl.getMsg("UserService.undoPasswd.Message.Failure") + e.getMessage());
        }

        return result;
    }

    public List<User> queryUserList(String loginName) {
//      this.addUser();
        List<User> userList = new ArrayList<User>();
        userList = (List<User>) this.userRepository.findAll();
//      User entity = this.userRepository.findUserByLoginName("xsding");
//        entity.setUserName("松哥");
//        this.userRepository.save(entity);
//        if (null != entity) {
//            this.userRepository.delete(entity);
//        }
        return userList;
    }

    public List<User> queryUserPagelist(Integer page, Integer size, final User userQuery) {
        List<User> userList = Collections.EMPTY_LIST;

        Pageable pageable = PageRequest.of(page, size, Sort.Direction.ASC, "pid");
        Page<User> userPage = this.userRepository.findAll(new Specification<User>(){
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                if ( StringUtils.isNotBlank(userQuery.getLoginName()) ){
                    list.add(criteriaBuilder.equal(root.get("loginName").as(String.class), userQuery.getLoginName()));
                }
                if ( StringUtils.isNotBlank(userQuery.getUserName()) ){
                    list.add(criteriaBuilder.equal(root.get("userName").as(String.class), userQuery.getUserName()));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, pageable);
        userList = userPage.getContent();

        return userList;
    }
}
